# coding=utf-8
# 实现关键字库


import pytesseract

from PIL import Image
from PIL import ImageGrab
import cv2, time, requests, uiautomation, random
from pymouse import PyMouse
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from three_robot.robot.services.driver_rt import Driver
from three_robot.robot.view.repoters import Repoter
from three_robot.robot.services.tools import print_exception


class Keylib:
    rsep = None  # 储存相应结果

    def __init__(self):
        self.s = requests.session()
        self.driver = Driver.get_driver()

    # @print_exception
    def post(self, kwargs):
        url = kwargs.get('url')
        body = kwargs.get('body')
        body = eval(body)
        headers = kwargs.get('herders')
        resp = self.s.post(url=url, data=body, headers=headers)
        self.resp = resp
        return True

    # @print_exception
    def get(self, kwargs):
        url = kwargs.get('url')
        body = kwargs.get('body')
        body = eval(body)
        headers = kwargs.get('herders')
        resp = self.s.get(url=url, params=body, headers=headers)
        if kwargs.get('expected') == resp.text:
            return True
        else:
            return False

    # @print_exception
    def wait(self, kwargs):
        try:
            time.sleep(float(kwargs.get('time')))
            return True
        except:
            raise ValueError('等待时间编写有误！')

    # @print_exception
    def open(self, kwargs):
        url = kwargs.get('url')
        resp = self.driver.get(url)
        if resp:
            return False
        else:
            return True

    def quit(self, kwargs):
        self.driver.quit()
        return True

    # @print_exception
    def input(self, kwargs):
        how, what, value = self.__get_tag(kwargs)
        element = self.__find_element(how, what)
        if element:
            element.send_keys(value if 'random' != value else 'RD_' + str(random.randint(1000, 9999)) + str(
                random.randint(1000, 9999)))
            return True
        else:
            print(f'未能找到元素：{how}={what}')
            return False

    # @print_exception
    def click(self, kwargs):
        how, what, value = self.__get_tag(kwargs)
        element = self.__find_element(how, what)
        if element:
            element.click()
            return True
        else:
            print(f'未能找到元素：{how}={what}')
            return False

    # 清空文本框内容
    # @print_exception
    def clear(self, kwargs):
        how, what, value = self.__get_tag(kwargs)
        element = self.__find_element(how, what)
        if element:
            element.clear()
            return True
        else:
            print(f'未能找到元素：{how}={what}')
            return False

    # @print_exception
    def broswer_back(self, kwargs):
        try:
            self.driver.back()
            return True
        except:
            raise Exception('浏览器返回操作执行失败！')

    # @print_exception
    def broswer_flush(self, kwargs):
        try:
            self.driver.refresh()
            return True
        except:
            raise Exception('浏览器刷新操作执行失败！')

    # @print_exception
    def windown_switch(self, kwargs):
        try:
            win = self.driver.window_handles[-1]
            self.driver.switch_to.window(win)
            return True
        except:
            return False

    # @print_exception
    def cv2_click(self, kwargs):
        try:
            how, what, smalldir = self.__get_tag(kwargs)
            ImageGrab.grab().save('./robot/a_big_screenshot/big.png')
            time.sleep(1)
            small = cv2.imread(rf'{smalldir}')
            big = cv2.imread(rf'./robot/a_big_screenshot/big.png')
            r = cv2.matchTemplate(small, big, cv2.TM_CCOEFF_NORMED)
            r1 = cv2.minMaxLoc(r)
            y, x = 0, 0
            # print(r1)
            if r1[1] > 0.7:
                x, y = r1[-1]
            else:
                print("找不到相似度匹配的图像")
            y1, x1, z1 = small.shape
            x2 = int(x + (x1 // 2))
            y2 = int(y + (y1 // 2))
            # print(x2, y2)
            m = PyMouse()
            m.click(int(x2), int(y2))
            # m.click(int(x2 // 1.5), int(y2 // 1.5))
            # print(int(x2 // 1.5), int(y2 // 1.5))
            return True
        except Exception as e:
            print(e)
            return False

    def push_file(self, kwargs):
        how, what, filename = self.__get_tag(kwargs)
        uiautomation.EditControl(ClassName='Edit').Click()
        uiautomation.EditControl(ClassName='Edit').SendKeys(filename)
        uiautomation.ButtonControl(Name="打开(O)").Click()
        return True

    def execute_js(self, kwargs):
        how, what, script = self.__get_tag(kwargs)
        self.driver.execute_script(script)
        return True

    # @print_exception
    def should_eq_title(self, kwargs):
        # kwargs == self.driver.title
        ...

    # @print_exception
    def shouldlink(self, kwargs):
        if WebDriverWait(self.driver, 5, 0.5).until(
                EC.presence_of_element_located((By.PARTIAL_LINK_TEXT, kwargs.get('text')))):
            print('用例执行通过！')
            Repoter.rst.append('pass')
            Repoter.passed += 1
            return True
        else:
            Repoter.fail += 1
            print('用例执行失败！')
            Repoter.rst.append('fail')
            return False

    def shouldtitle(self, kwargs):
        if self.driver.title == kwargs.get('text'):
            print('用例执行通过！')
            Repoter.rst.append('pass')
            Repoter.passed += 1
            return True
        else:
            Repoter.fail += 1
            print('用例执行失败！')
            Repoter.rst.append('fail')
            return False

    def shouldclassname(self, kwargs):
        if WebDriverWait(self.driver, 5, 0.5).until(
                EC.presence_of_element_located((By.CLASS_NAME, kwargs.get('text')))):
            print('用例执行通过！')
            Repoter.rst.append('pass')
            Repoter.passed += 1
            return True
        else:
            Repoter.fail += 1
            print('用例执行失败！')
            Repoter.rst.append('fail')
            return False

    # 文本包含在返回页面中
    # @print_exception
    def shouldin(self, kwargs):
        texts = self.driver.page_source
        if kwargs.get('text') in texts:
            print('用例执行通过！')
            Repoter.rst.append('pass')
            Repoter.passed += 1
            return True
        else:
            Repoter.fail += 1
            print('用例执行失败！')
            Repoter.rst.append('fail')
            return False

    # 返回内容和预期结果相同
    # @print_exception
    def shouldeq(self, kwargs):
        if kwargs.get('expected') == self.resp.text:
            print('用例执行通过！')
            Repoter.rst.append('pass')
            Repoter.passed += 1
            return True
        else:
            Repoter.fail += 1
            print('用例执行失败！')
            Repoter.rst.append('fail')
            return False

    def shouldelement(self, kwargs):
        if WebDriverWait(self.driver, 5, 0.5).until(
                EC.presence_of_element_located((By.XPATH, kwargs.get('text')))):
            print('用例执行通过！')
            Repoter.rst.append('pass')
            Repoter.passed += 1
            return True
        else:
            Repoter.fail += 1
            print('用例执行失败！')
            Repoter.rst.append('fail')
            return False

    # 返回结果与预期相匹配
    # @print_exception
    def shouldcontains(self, kwargs):
        pass

    # 从字典中抽取数据
    # @print_exception
    def __get_tag(self, dict):
        how, what, value = None, None, None
        for k, v in dict.items():
            if k != 'value' and k != 'small' and k != 'filename' and k != 'script':
                how = k
                what = v
            else:
                value = v
        return how, what, value

    # 根据页面标签定位页面元素，可设置超时时间，默认5秒
    # def __find_element(self, how, what, timeout=5):
    #     for i in range(timeout):
    #         try:
    #             element = self.driver.find_element(how, what)
    #             return element
    #         except:
    #             time.sleep(1)
    #     return None
    # @print_exception
    def __find_element(self, how, what):
        try:
            element = WebDriverWait(self.driver, 5).until(EC.presence_of_element_located((how, what)))
            if element:
                return element
            else:
                return None
        except:
            raise Exception('找不到指定对象！')

    # 以下为项目专用函数
    def login(self, item):
        for u, p in item.items():
            self.driver.find_element_by_name('username').send_keys(u)
            self.driver.find_element_by_name('password').send_keys(p)
            ele = self.driver.find_element_by_xpath(r'//*[@id="app"]/div/section/main/div/div[1]/form/div[4]/img')
            ele.screenshot('./robot/a_verifycode/verify.png')
            image = Image.open('./robot/a_verifycode/verify.png')
            image = image.point(lambda x: 0 if x < 143 else 255)
            str = pytesseract.image_to_string(image)
            self.driver.find_element_by_name('verification').send_keys(str.strip().replace(' ', ''))
            time.sleep(0.5)
            self.driver.find_element_by_xpath('//button[@id="aaa"]').click()
        for i in range(10):
            time.sleep(0.5)
            if self.find_element('id', 'aaa'):
                self.driver.refresh()
                self.driver.find_element_by_name('username').send_keys(u)
                self.driver.find_element_by_name('password').send_keys(p)
                ele = self.driver.find_element_by_xpath(r'//*[@id="app"]/div/section/main/div/div[1]/form/div[4]/img')
                ele.screenshot('./robot/a_verifycode/verify.png')
                image = Image.open('./robot/a_verifycode/verify.png')
                image = image.point(lambda x: 0 if x < 143 else 255)
                str = pytesseract.image_to_string(image)
                self.driver.find_element_by_name('verification').send_keys(str.strip().replace(' ', ''))
                time.sleep(0.5)
                self.driver.find_element_by_xpath('//button[@id="aaa"]').click()
            else:
                break
        return True

    def input_time(self, kwargs):
        YM = str(random.randint(1000, 9999)) + '-' + str(random.randint(1, 12))
        day = random.randint(1, 31)
        star = YM + '-' + str(day)
        end = YM + '-' + str(day + 1)
        self.driver.find_element_by_xpath('/html/body/div[2]/div[1]/div/div[1]/span[1]/span[2]/div[1]/input').click()
        time.sleep(0.5)
        self.driver.find_element_by_xpath('/html/body/div[2]/div[1]/div/div[1]/span[1]/span[1]/div/input').clear()
        time.sleep(0.5)
        self.driver.find_element_by_xpath('/html/body/div[2]/div[1]/div/div[1]/span[1]/span[1]/div/input').send_keys(
            star)

        self.driver.find_element_by_xpath('/html/body/div[2]/div[1]/div/div[1]/span[3]/span[1]/div/input').clear()
        time.sleep(0.5)
        self.driver.find_element_by_xpath('/html/body/div[2]/div[1]/div/div[1]/span[3]/span[1]/div/input').send_keys(
            end)
        self.driver.find_element_by_xpath('/html/body/div[2]/div[2]/button[2]').click()
        return True

    def find_element(self, how, what):
        try:
            element = WebDriverWait(self.driver, 2).until(EC.presence_of_element_located((how, what)))
            if element:
                return True
        except:
            return False
